/*
 * Szene.h
 *
 *  Created on: Feb 15, 2011
 *      Author: alki
 */

#ifndef SZENE_H_
#define SZENE_H_

#include "objekte/Objekt.h"
#include "objekte/Material.h"
#include "objekte/Textur.h"
#include "objekte/KDTree.h"

#include "math/Vektor.h"

#include "manager/MaterialManager.h"

#include <vector>

#define OBJEKT this->m_objekte[4]
#define OBJEKT2 this->m_objekte[0]
#define OBJEKT3 this->m_objekte[1]
#define OBJEKT4 this->m_objekte[2]
#define OBJEKT5 this->m_objekte[3]
#define INTERSEC(ray) OBJEKT.Intersects(ray)
#define LINKS(ray) (ray.getDir().getX()<=0)
#define OBEN(ray) (ray.getDir().getY()>=0)

enum STRAHL {
	diffus,
	specular
};

/**
 * Klasse Szene: kümmert sich um alle Aufgaben, die auf die Szene zukommen (laden, berechnen der Strahlen,...)
 */
class Szene {
public:
	Szene(unsigned int width,unsigned int height,unsigned int jitter=1,unsigned int diffus=1,unsigned int maxtiefe=0);
	virtual ~Szene();

	void LoadFile(string filename);

	FARBE CalcRay(unsigned int x,unsigned int y) const;
	FARBE CalcRay(const Gerade &ray,unsigned int tiefe=0) const;

	void setPosition(Vektor pos) { this->m_pos=pos; }
	void setDirection(Vektor dir) { this->m_dir=dir; }
	Vektor getPosition() const { return this->m_pos; }
	Vektor getDirection() const { return this->m_dir; }
	unsigned int getWidth() const { return this->m_width; }

	void AddObject(Objekt obj) { this->m_objekte.push_back(obj); }
private:
	MaterialManager m_matman;

	vector<Objekt> m_objekte;

	KDTree *m_tree;

	Vektor m_pos;
	Vektor m_dir;

	unsigned int m_width;
	unsigned int m_height;
	unsigned int m_jitter;
	unsigned int m_diffus;
	unsigned int m_maxtiefe;

	Vektor Pixel2Dir(unsigned int x,unsigned int y) const;
	inline int FARBE2INT(FARBE f) const;

	Vektor CalcDir(const Vektor &dir,const Vektor &n,STRAHL s) const;
};

#endif /* SZENE_H_ */
